package com.sscw.task.service.impl;

import cn.hutool.core.date.LocalDateTimeUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.guaike.core.entity.enums.EnableStatusEnum;
import com.sscw.task.constant.MQTTTopicConstant;
import com.sscw.task.dao.*;
import com.sscw.task.entity.*;
import com.sscw.task.enums.*;
import com.sscw.task.mqtt.MQTTProducer;
import com.sscw.task.service.DealJobService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

@Slf4j
@Service
@AllArgsConstructor
public class DealJobServiceImpl implements DealJobService {

    private final MRecordPineDAO mRecordPineDAO;
    private final DDetailsPineconeDAO dDetailsPineconeDAO;
    private final DDetailsPineNutDAO detailsPineNutDAO;
    private final UAppUserDAO uAppUserDAO;
    private final UAppUserEquityDAO uAppUserEquityDAO;
    private final MRankPineconeDAO mRankPineconeDAO;
    private final MConfRankDAO mConfRankDAO;
    private final MConfRankPrizeDAO mConfRankPrizeDAO;
    private final MConfBattleDAO mConfBattleDAO;
    private final MConfBattlePrizeDAO mConfBattlePrizeDAO;
    private final MRankRichDAO mRankRichDAO;
    private final MRankPushCoinsDAO mRankPushCoinsDAO;
    private final MRankArcadeMachineDAO mRankArcadeMachineDAO;
    private final GRecordGameDAO gRecordGameDAO;
    private final MRankBattleArcadeMachineDAO mRankBattleArcadeMachineDAO;
    private final MRankBattlePushCoinsDAO mRankBattlePushCoinsDAO;
    private final MRankBattleRecreationDAO mRankBattleRecreationDAO;
    private final MRecordProductCardDAO mRecordProductCardDAO;
    private final MQTTProducer mqttProducer;
    private final MConfVipDAO mConfVipDAO;
    private final GRecordMqttMessageDAO gRecordMqttMessageDAO;
    private final MRecordOccupyDAO mRecordOccupyDAO;
    private final GConfDeviceDAO gConfDeviceDAO;

    @Override
    @Transactional
    public void pineSettleJobHandler() {
        LocalDate today = LocalDate.now();
        LocalDate lastLastMonday = today.with(DayOfWeek.MONDAY).minusWeeks(2);
        LocalDate lastLastSunday = today.with(DayOfWeek.SUNDAY).minusWeeks(2);
        while (true) {
            List<MRecordPinePO> pinePOS = mRecordPineDAO.findCanGetPine(lastLastMonday, lastLastSunday);
            if (CollectionUtils.isEmpty(pinePOS)) {
                break;
            }
            pinePOS.forEach(pinePO -> {
                uAppUserEquityDAO.addPinecone(pinePO.getUserId(), pinePO.getGetPinecone());
                DDetailsPineconePO myDetail = new DDetailsPineconePO();
                myDetail.setUserId(pinePO.getUserId());
                myDetail.setLabelType(LabelTypeEnum.pine.getCode());
                myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
                myDetail.setPinecone(pinePO.getGetPinecone());
                myDetail.setCreateUser(-1L);
                myDetail.setCreateTime(LocalDateTime.now());
                myDetail.setUpdateUser(-1L);
                myDetail.setUpdateTime(LocalDateTime.now());
                dDetailsPineconeDAO.save(myDetail);
            });
            List<Long> ids = pinePOS.stream().map(MRecordPinePO::getId).collect(Collectors.toList());
            mRecordPineDAO.updateIsGet(ids);
        }
    }

    @Override
    @Transactional
    public void pineconeRankJobHandler() {
        List<UAppUserEquityPO> equityPOS = uAppUserEquityDAO.findTop20Pinecone();
        if (CollectionUtils.isEmpty(equityPOS)) {
            return;
        }
        LocalDate today = LocalDate.now();
        LocalDate lastMonday = today.with(DayOfWeek.MONDAY).minusWeeks(1);
        LocalDate lastSunday = today.with(DayOfWeek.SUNDAY).minusWeeks(1);
        List<Long> userIds = equityPOS.stream().map(UAppUserEquityPO::getUserId).collect(Collectors.toList());
        List<UAppUserPO> userPOS = uAppUserDAO.findByIdList(userIds);
        Map<Long, List<UAppUserPO>> listMap = userPOS.stream().collect(Collectors.groupingBy(UAppUserPO::getId));
        List<MRankPineconePO> list = new ArrayList<>();
        for (int i = 0; i < equityPOS.size(); i++) {
            UAppUserEquityPO po = equityPOS.get(i);
            MRankPineconePO rankPO = new MRankPineconePO();
            rankPO.setUserId(po.getUserId());
            rankPO.setNickname(listMap.get(po.getUserId()).get(0).getNickname());
            rankPO.setAvatarurl(listMap.get(po.getUserId()).get(0).getAvatarurl());
            rankPO.setVipGrade(po.getVipGrade());
            rankPO.setPinecone(po.getPinecone());
            rankPO.setRankNo(i + 1);
            rankPO.setStartDate(lastMonday);
            rankPO.setEndDate(lastSunday);
            rankPO.setCreateUser(-1L);
            rankPO.setCreateTime(LocalDateTime.now());
            rankPO.setUpdateUser(-1L);
            rankPO.setUpdateTime(LocalDateTime.now());
            list.add(rankPO);
        }
        mRankPineconeDAO.saveBatch(list);
    }

    @Override
    @Transactional
    public void richRankJobHandler() {
        MConfRankPO confRankPO = mConfRankDAO.findOne(MConfRankPO::getRankCode, RankCodeEnum.hq.getCode());
        if (confRankPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
            return;
        }
        LocalDate today = LocalDate.now();
        LocalDate yesterday = today.minusDays(1);
        List<MConfRankPrizePO> rankPrizePOS = mConfRankPrizeDAO.findList(MConfRankPrizePO::getRankId, confRankPO.getId(), MConfRankPrizePO::getRankNo, Boolean.TRUE);
        List<MRankRichPO> richPOS = mRankRichDAO.findYesRankList(yesterday, rankPrizePOS.size());
        if (CollectionUtils.isEmpty(richPOS)) {
            return;
        }
        for (int i = 0; i < richPOS.size(); i++) {
            MRankRichPO richPO = richPOS.get(i);
            MConfRankPrizePO confRankPrizePO = rankPrizePOS.get(i);
            richPO.setRankNo(confRankPrizePO.getRankNo());
            richPO.setIsRank(Boolean.TRUE);
            richPO.setGetPinecone(confRankPrizePO.getPinecone());
            uAppUserEquityDAO.addPinecone(richPO.getUserId(), confRankPrizePO.getPinecone());
            DDetailsPineconePO myDetail = new DDetailsPineconePO();
            myDetail.setUserId(richPO.getUserId());
            myDetail.setLabelType(LabelTypeEnum.rank_list.getCode());
            myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
            myDetail.setPinecone(confRankPrizePO.getPinecone());
            myDetail.setRemark("财富排行榜（" + LocalDateTimeUtil.format(yesterday, "yyyy-MM-dd") + "）第" + confRankPrizePO.getRankNo() + "名");
            myDetail.setCreateUser(-1L);
            myDetail.setCreateTime(LocalDateTime.now());
            myDetail.setUpdateUser(-1L);
            myDetail.setUpdateTime(LocalDateTime.now());
            dDetailsPineconeDAO.save(myDetail);
        }
        mRankRichDAO.updateBatchById(richPOS);
    }

    @Override
    public void pushCoinsRankJobHandler() {
        MConfRankPO confRankPO = mConfRankDAO.findOne(MConfRankPO::getRankCode, RankCodeEnum.gs.getCode());
        if (confRankPO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
            return;
        }
        LocalDate today = LocalDate.now();
        LocalDate lastMonday = today.with(DayOfWeek.MONDAY).minusWeeks(1);
        LocalDate lastSunday = today.with(DayOfWeek.SUNDAY).minusWeeks(1);
        List<MConfRankPrizePO> rankPrizePOS = mConfRankPrizeDAO.findList(MConfRankPrizePO::getRankId, confRankPO.getId(), MConfRankPrizePO::getRankNo, Boolean.TRUE);
        List<MRankPushCoinsPO> pushCoinsPOS = mRankPushCoinsDAO.findWeekRankList(lastMonday, lastSunday, rankPrizePOS.size());
        if (CollectionUtils.isEmpty(pushCoinsPOS)) {
            return;
        }
        for (int i = 0; i < pushCoinsPOS.size(); i++) {
            MRankPushCoinsPO pushCoinsPO = pushCoinsPOS.get(i);
            MConfRankPrizePO confRankPrizePO = rankPrizePOS.get(i);
            pushCoinsPO.setRankNo(confRankPrizePO.getRankNo());
            pushCoinsPO.setIsRank(Boolean.TRUE);
            pushCoinsPO.setGetPinecone(confRankPrizePO.getPinecone());
            uAppUserEquityDAO.addPinecone(pushCoinsPO.getUserId(), confRankPrizePO.getPinecone());
            DDetailsPineconePO myDetail = new DDetailsPineconePO();
            myDetail.setUserId(pushCoinsPO.getUserId());
            myDetail.setLabelType(LabelTypeEnum.rank_list.getCode());
            myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
            myDetail.setPinecone(confRankPrizePO.getPinecone());
            myDetail.setRemark("推币高手排行榜（" + LocalDateTimeUtil.format(lastMonday, "yyyy-MM-dd") + "-" + LocalDateTimeUtil.format(lastSunday, "yyyy-MM-dd") + "）第" + confRankPrizePO.getRankNo() + "名");
            myDetail.setCreateUser(-1L);
            myDetail.setCreateTime(LocalDateTime.now());
            myDetail.setUpdateUser(-1L);
            myDetail.setUpdateTime(LocalDateTime.now());
            dDetailsPineconeDAO.save(myDetail);
        }
        mRankPushCoinsDAO.updateBatchById(pushCoinsPOS);
    }

    @Override
    public void arcadeMachineRankJobHandler() {
        LocalDate today = LocalDate.now();
        LocalDate lastMonday = today.with(DayOfWeek.MONDAY).minusWeeks(1);
        LocalDate lastSunday = today.with(DayOfWeek.SUNDAY).minusWeeks(1);
        MConfRankPO confRankPO = mConfRankDAO.findOne(MConfRankPO::getRankCode, RankCodeEnum.cw_low.getCode());
        if (confRankPO.getStatus().equals(EnableStatusEnum.ENABLE.getCode())) {
            List<MConfRankPrizePO> rankPrizePOS = mConfRankPrizeDAO.findList(MConfRankPrizePO::getRankId, confRankPO.getId(), MConfRankPrizePO::getRankNo, Boolean.TRUE);
            List<MRankArcadeMachinePO> machinePOS = mRankArcadeMachineDAO.findWeekRankList(lastMonday, lastSunday, RankTypeEnum.low_machine.getCode(), rankPrizePOS.size());
            for (int i = 0; i < machinePOS.size(); i++) {
                MRankArcadeMachinePO machinePO = machinePOS.get(i);
                MConfRankPrizePO confRankPrizePO = rankPrizePOS.get(i);
                machinePO.setRankNo(confRankPrizePO.getRankNo());
                machinePO.setIsRank(Boolean.TRUE);
                machinePO.setGetPinecone(confRankPrizePO.getPinecone());
                uAppUserEquityDAO.addPinecone(machinePO.getUserId(), confRankPrizePO.getPinecone());
                DDetailsPineconePO myDetail = new DDetailsPineconePO();
                myDetail.setUserId(machinePO.getUserId());
                myDetail.setLabelType(LabelTypeEnum.rank_list.getCode());
                myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
                myDetail.setPinecone(confRankPrizePO.getPinecone());
                myDetail.setRemark("潮玩达人低倍房排行榜（" + LocalDateTimeUtil.format(lastMonday, "yyyy-MM-dd") + "-" + LocalDateTimeUtil.format(lastSunday, "yyyy-MM-dd") + "）第" + confRankPrizePO.getRankNo() + "名");
                myDetail.setCreateUser(-1L);
                myDetail.setCreateTime(LocalDateTime.now());
                myDetail.setUpdateUser(-1L);
                myDetail.setUpdateTime(LocalDateTime.now());
                dDetailsPineconeDAO.save(myDetail);
            }
            if (CollectionUtils.isNotEmpty(machinePOS)) {
                mRankArcadeMachineDAO.updateBatchById(machinePOS);
            }
        }
        MConfRankPO mConfRankPO = mConfRankDAO.findOne(MConfRankPO::getRankCode, RankCodeEnum.cw_high.getCode());
        if (mConfRankPO.getStatus().equals(EnableStatusEnum.ENABLE.getCode())) {
            List<MConfRankPrizePO> rankPrizePOS = mConfRankPrizeDAO.findList(MConfRankPrizePO::getRankId, mConfRankPO.getId(), MConfRankPrizePO::getRankNo, Boolean.TRUE);
            List<MRankArcadeMachinePO> machinePOS = mRankArcadeMachineDAO.findWeekRankList(lastMonday, lastSunday, RankTypeEnum.high_machine.getCode(), rankPrizePOS.size());
            for (int i = 0; i < machinePOS.size(); i++) {
                MRankArcadeMachinePO machinePO = machinePOS.get(i);
                MConfRankPrizePO confRankPrizePO = rankPrizePOS.get(i);
                machinePO.setRankNo(confRankPrizePO.getRankNo());
                machinePO.setIsRank(Boolean.TRUE);
                machinePO.setGetPinecone(confRankPrizePO.getPinecone());
                uAppUserEquityDAO.addPinecone(machinePO.getUserId(), confRankPrizePO.getPinecone());
                DDetailsPineconePO myDetail = new DDetailsPineconePO();
                myDetail.setUserId(machinePO.getUserId());
                myDetail.setLabelType(LabelTypeEnum.rank_list.getCode());
                myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
                myDetail.setPinecone(confRankPrizePO.getPinecone());
                myDetail.setRemark("潮玩达人高倍房排行榜（" + LocalDateTimeUtil.format(lastMonday, "yyyy-MM-dd") + "-" + LocalDateTimeUtil.format(lastSunday, "yyyy-MM-dd") + "）第" + confRankPrizePO.getRankNo() + "名");
                myDetail.setCreateUser(-1L);
                myDetail.setCreateTime(LocalDateTime.now());
                myDetail.setUpdateUser(-1L);
                myDetail.setUpdateTime(LocalDateTime.now());
                dDetailsPineconeDAO.save(myDetail);
            }
            if (CollectionUtils.isNotEmpty(machinePOS)) {
                mRankArcadeMachineDAO.updateBatchById(machinePOS);
            }
        }
    }

    @Override
    public void pushCoinsBattleRankJobHandler() {
        LocalDate today = LocalDate.now();
        LocalDate yesToday = today.minusDays(1);
        MConfBattlePO confBattlePO = mConfBattleDAO.findOne(MConfBattlePO::getRankCode, BattleRankCodeEnum.tbj.getCode());
        if (Objects.isNull(confBattlePO) || confBattlePO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
            return;
        }
        List<MConfBattlePrizePO> prizePOS = mConfBattlePrizeDAO.findList(MConfBattlePrizePO::getRankId, confBattlePO.getId(), MConfBattlePrizePO::getRankNo, Boolean.TRUE);
        List<GRecordGamePO> pos = gRecordGameDAO.findRankRecord(RoomTypeEnum.push_coins.getCode(), yesToday, prizePOS.size());
        if (CollectionUtils.isNotEmpty(pos)) {
            List<Long> userIds = pos.stream().map(GRecordGamePO::getUserId).collect(Collectors.toList());
            List<UAppUserPO> userPOS = uAppUserDAO.findByIdList(userIds);
            Map<Long, List<UAppUserPO>> listMap = userPOS.stream().collect(Collectors.groupingBy(UAppUserPO::getId));
            List<UAppUserEquityPO> equityPOS = uAppUserEquityDAO.findIn(UAppUserEquityPO::getUserId, userIds);
            Map<Long, List<UAppUserEquityPO>> listMap1 = equityPOS.stream().collect(Collectors.groupingBy(UAppUserEquityPO::getUserId));
            List<MRankBattlePushCoinsPO> list = new ArrayList<>();
            for (int i = 0; i < pos.size(); i++) {
                GRecordGamePO gamePO = pos.get(i);
                MConfBattlePrizePO prizePO = prizePOS.get(i);
                MRankBattlePushCoinsPO po = new MRankBattlePushCoinsPO();
                po.setUserId(gamePO.getUserId());
                po.setNickname(listMap.get(gamePO.getUserId()).get(0).getNickname());
                po.setAvatarurl(listMap.get(gamePO.getUserId()).get(0).getAvatarurl());
                po.setVipGrade(listMap1.get(gamePO.getUserId()).get(0).getVipGrade());
                po.setRoomName(gamePO.getRoomName());
                po.setPineNut(gamePO.getGetPineNut().intValue());
                po.setPinecone(prizePO.getPinecone());
                po.setIsRank(Boolean.TRUE);
                po.setRankNo(prizePO.getRankNo());
                po.setRankDate(yesToday);
                po.setCreateUser(-1L);
                po.setCreateTime(LocalDateTime.now());
                po.setUpdateUser(-1L);
                po.setUpdateTime(LocalDateTime.now());
                list.add(po);
            }
            mRankBattlePushCoinsDAO.saveBatch(list);
        }
    }

    @Override
    public void recreationBattleRankJobHandler() {
        LocalDate today = LocalDate.now();
        LocalDate yesToday = today.minusDays(1);
        MConfBattlePO confBattlePO = mConfBattleDAO.findOne(MConfBattlePO::getRankCode, BattleRankCodeEnum.yl.getCode());
        if (Objects.isNull(confBattlePO) || confBattlePO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
            return;
        }
        List<MConfBattlePrizePO> prizePOS = mConfBattlePrizeDAO.findList(MConfBattlePrizePO::getRankId, confBattlePO.getId(), MConfBattlePrizePO::getRankNo, Boolean.TRUE);
        List<GRecordGamePO> pos = gRecordGameDAO.findRankRecord(RoomTypeEnum.recreation.getCode(), yesToday, prizePOS.size());
        if (CollectionUtils.isNotEmpty(pos)) {
            List<Long> userIds = pos.stream().map(GRecordGamePO::getUserId).collect(Collectors.toList());
            List<UAppUserPO> userPOS = uAppUserDAO.findByIdList(userIds);
            Map<Long, List<UAppUserPO>> listMap = userPOS.stream().collect(Collectors.groupingBy(UAppUserPO::getId));
            List<UAppUserEquityPO> equityPOS = uAppUserEquityDAO.findIn(UAppUserEquityPO::getUserId, userIds);
            Map<Long, List<UAppUserEquityPO>> listMap1 = equityPOS.stream().collect(Collectors.groupingBy(UAppUserEquityPO::getUserId));
            List<MRankBattleRecreationPO> list = new ArrayList<>();
            for (int i = 0; i < pos.size(); i++) {
                GRecordGamePO gamePO = pos.get(i);
                MConfBattlePrizePO prizePO = prizePOS.get(i);
                MRankBattleRecreationPO po = new MRankBattleRecreationPO();
                po.setUserId(gamePO.getUserId());
                po.setNickname(listMap.get(gamePO.getUserId()).get(0).getNickname());
                po.setAvatarurl(listMap.get(gamePO.getUserId()).get(0).getAvatarurl());
                po.setVipGrade(listMap1.get(gamePO.getUserId()).get(0).getVipGrade());
                po.setRoomName(gamePO.getRoomName());
                po.setPineNut(gamePO.getGetPineNut().intValue());
                po.setPinecone(prizePO.getPinecone());
                po.setIsRank(Boolean.TRUE);
                po.setRankNo(prizePO.getRankNo());
                po.setRankDate(yesToday);
                po.setCreateUser(-1L);
                po.setCreateTime(LocalDateTime.now());
                po.setUpdateUser(-1L);
                po.setUpdateTime(LocalDateTime.now());
                list.add(po);
            }
            mRankBattleRecreationDAO.saveBatch(list);
        }
    }

    @Override
    public void arcadeMachineBattleRankJobHandler() {
        LocalDate today = LocalDate.now();
        LocalDate yesToday = today.minusDays(1);
        MConfBattlePO confBattlePO = mConfBattleDAO.findOne(MConfBattlePO::getRankCode, BattleRankCodeEnum.jj.getCode());
        if (Objects.isNull(confBattlePO) || confBattlePO.getStatus().equals(EnableStatusEnum.DISABLE.getCode())) {
            return;
        }
        List<MConfBattlePrizePO> prizePOS = mConfBattlePrizeDAO.findList(MConfBattlePrizePO::getRankId, confBattlePO.getId(), MConfBattlePrizePO::getRankNo, Boolean.TRUE);
        List<GRecordGamePO> pos = gRecordGameDAO.findRankRecord(RoomTypeEnum.arcade_machine.getCode(), yesToday, prizePOS.size());
        if (CollectionUtils.isNotEmpty(pos)) {
            List<Long> userIds = pos.stream().map(GRecordGamePO::getUserId).collect(Collectors.toList());
            List<UAppUserPO> userPOS = uAppUserDAO.findByIdList(userIds);
            Map<Long, List<UAppUserPO>> listMap = userPOS.stream().collect(Collectors.groupingBy(UAppUserPO::getId));
            List<UAppUserEquityPO> equityPOS = uAppUserEquityDAO.findIn(UAppUserEquityPO::getUserId, userIds);
            Map<Long, List<UAppUserEquityPO>> listMap1 = equityPOS.stream().collect(Collectors.groupingBy(UAppUserEquityPO::getUserId));
            List<MRankBattleArcadeMachinePO> list = new ArrayList<>();
            for (int i = 0; i < pos.size(); i++) {
                GRecordGamePO gamePO = pos.get(i);
                MConfBattlePrizePO prizePO = prizePOS.get(i);
                MRankBattleArcadeMachinePO po = new MRankBattleArcadeMachinePO();
                po.setUserId(gamePO.getUserId());
                po.setNickname(listMap.get(gamePO.getUserId()).get(0).getNickname());
                po.setAvatarurl(listMap.get(gamePO.getUserId()).get(0).getAvatarurl());
                po.setVipGrade(listMap1.get(gamePO.getUserId()).get(0).getVipGrade());
                po.setRoomName(gamePO.getRoomName());
                po.setPineNut(gamePO.getGetPineNut().intValue());
                po.setPinecone(prizePO.getPinecone());
                po.setIsRank(Boolean.TRUE);
                po.setRankNo(prizePO.getRankNo());
                po.setRankDate(yesToday);
                po.setCreateUser(-1L);
                po.setCreateTime(LocalDateTime.now());
                po.setUpdateUser(-1L);
                po.setUpdateTime(LocalDateTime.now());
                list.add(po);
            }
            mRankBattleArcadeMachineDAO.saveBatch(list);
        }
    }

    @Override
    public void settleArcadeMachineJobHandler() {
        List<GRecordGamePO> needSettle = gRecordGameDAO.findNeedSettle();
        needSettle.forEach(po -> {
            if (Objects.nonNull(po.getRecordOccupyId())) {
                MRecordOccupyPO occupyPO = mRecordOccupyDAO.findById(po.getRecordOccupyId());
                boolean after = (po.getCreateTime().plusMinutes(occupyPO.getDuration())).isAfter(LocalDateTime.now());
                if (after) {
                    return;
                }
            }
            mqttProducer.sendIoMessage(MQTTTopicConstant.SETTLE_MACHINE, String.valueOf(po.getId()), 1);
        });
    }

    @Override
    public void settlePushCoinsOccupyJobHandler() {
        List<MRecordOccupyPO> noSettleRecord = mRecordOccupyDAO.findNoSettleRecord();
        noSettleRecord.forEach(occupyPO -> {
            Integer pinecone = occupyPO.getCurrentPinecone() > occupyPO.getPinecone() ? occupyPO.getCurrentPinecone() : occupyPO.getPinecone();
            uAppUserEquityDAO.addPinecone(occupyPO.getUserId(), pinecone);
            DDetailsPineconePO myDetail = new DDetailsPineconePO();
            myDetail.setUserId(occupyPO.getUserId());
            myDetail.setLabelType(LabelTypeEnum.occupy.getCode());
            myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
            myDetail.setPinecone(pinecone);
            myDetail.setRemark("包机记录ID:" + occupyPO.getId());
            dDetailsPineconeDAO.save(myDetail);
            mRecordOccupyDAO.updateSettleEnd(occupyPO.getId());
        });
    }

    @Override
    public void settlePushCoinsJobHandler() {
        List<GConfDevicePO> allPushCoinsUse = gConfDeviceDAO.findAllPushCoinsUse();
        allPushCoinsUse.forEach(devicePO -> {
            long playing = gRecordGameDAO.checkPlaying(devicePO.getId());
            if (playing == 0) {
                //需要下机
                mqttProducer.sendIoMessage(MQTTTopicConstant.SETTLE_PUSH_COINS, devicePO.getSerialNumber(), 1);
            }
        });
    }

    @Override
    @Transactional
    public void grantCardJobHandler() {
        List<MRecordProductCardPO> cardPOS = mRecordProductCardDAO.findNeedGrantCard();
        cardPOS.forEach(po -> {
            uAppUserEquityDAO.addPinecone(po.getUserId(), po.getDailyPinecone());
            DDetailsPineconePO myDetail = new DDetailsPineconePO();
            myDetail.setUserId(po.getUserId());
            if (po.getCardType().equals(CardTypeEnum.week_card.getCode())) {
                myDetail.setLabelType(LabelTypeEnum.week_card.getCode());
            } else {
                myDetail.setLabelType(LabelTypeEnum.month_card.getCode());
            }
            myDetail.setDetailsType(DetailsTypeEnum.income.getCode());
            myDetail.setPinecone(po.getDailyPinecone());
            myDetail.setCreateUser(-1L);
            myDetail.setCreateTime(LocalDateTime.now());
            myDetail.setUpdateUser(-1L);
            myDetail.setUpdateTime(LocalDateTime.now());
            dDetailsPineconeDAO.save(myDetail);
        });
        List<Long> ids = cardPOS.stream().map(MRecordProductCardPO::getId).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(ids)) {
            mRecordProductCardDAO.reduceDay(ids);
        }
    }

    @Override
    public void grantEquityJobHandler() {
        Integer pageIndex = 1;
        Integer pageSize = 20;
        while (true) {
            Page<UAppUserPO> poPage = uAppUserDAO.findPage(pageIndex, pageSize);
            List<UAppUserPO> records = poPage.getRecords();
            if (CollectionUtils.isEmpty(records)) {
                break;
            }
            List<Long> ids = records.stream().map(UAppUserPO::getId).collect(Collectors.toList());
            List<UAppUserEquityPO> equityPOS = uAppUserEquityDAO.findIn(UAppUserEquityPO::getUserId, ids);
            List<Integer> vipList = equityPOS.stream().map(UAppUserEquityPO::getVipGrade).collect(Collectors.toList());
            List<MConfVipPO> vipPOS = mConfVipDAO.findIn(MConfVipPO::getVipLevel, vipList);
            Map<Integer, List<MConfVipPO>> listMap = vipPOS.stream().collect(Collectors.groupingBy(MConfVipPO::getVipLevel));
            List<UAppUserEquityPO> updateList = new ArrayList<>();
            equityPOS.forEach(equityPO -> {
                UAppUserEquityPO po = new UAppUserEquityPO();
                po.setId(equityPO.getId());
                MConfVipPO vipPO = listMap.get(equityPO.getVipGrade()).get(0);
                po.setForbidLookThirty(vipPO.getUnalowLookNum());
                po.setLockFifteen(vipPO.getLock15Num());
                po.setLockThirty(vipPO.getLock30Num());
                po.setLockSixty(vipPO.getLock60Num());
                updateList.add(po);
            });
            if (CollectionUtils.isNotEmpty(updateList)) {
                uAppUserEquityDAO.updateBatchById(updateList);
            }
            pageIndex++;
        }
    }

    @Override
    public void deleteMqttMessageJobHandler() {
        gRecordMqttMessageDAO.deleteBeforeTwoDaysMessage();
    }

    @Override
    public void deleteDetailsJobHandler() {
//        LocalDate now = LocalDate.now();
//        LocalDate limitDate = now.minusDays(2);
//        LocalDateTime  limitDateTime = limitDate.atStartOfDay();
//        log.info("【deleteDetailsJobHandler】清理数据截止日期: {}", limitDateTime);

        dDetailsPineconeDAO.deleteBeforeDay(4);
        detailsPineNutDAO.deleteBeforeDay(4);

    }
}
